"""
@description 网络工具核心功能模块
"""
import socket
import psutil
import speedtest
import requests
import platform
import subprocess
import dns.resolver  # 新增：用于DNS测试
from typing import Dict, List
import time
import threading
from queue import Queue

class NetworkUtils:
    """
    @description 网络工具类，提供各种网络诊断和测试功能
    """
    
    @staticmethod
    def get_network_info() -> Dict:
        """
        @description 获取网络接口信息
        @returns {Dict} 网络信息字典
        """
        try:
            network_info = {}
            interfaces = psutil.net_if_addrs()
            
            for interface, addrs in interfaces.items():
                network_info[interface] = []
                for addr in addrs:
                    if addr.family == socket.AF_INET:  # 只获取IPv4地址
                        network_info[interface].append({
                            'ip': addr.address,
                            'netmask': addr.netmask,
                            'broadcast': addr.broadcast
                        })
            return {
                "status": True,
                "data": network_info,
                "message": "获取网络信息成功"
            }
        except Exception as e:
            return {
                "status": False,
                "message": f"获取网络信息失败: {str(e)}"
            }

    @staticmethod
    def check_internet_connection() -> Dict:
        """
        @description 检查互联网连接
        @returns {Dict} 连接状态信息
        """
        try:
            requests.get('http://www.baidu.com', timeout=3)
            return {
                "status": True,
                "message": "网络连接正常"
            }
        except requests.RequestException:
            return {
                "status": False,
                "message": "网络连接失败"
            }

    @staticmethod
    def ping_test(host: str = "8.8.8.8") -> Dict:
        """
        @description 进行ping测试
        @param {str} host - 目标主机地址
        @returns {Dict} ping测试结果
        """
        param = '-n' if platform.system().lower() == 'windows' else '-c'
        command = ['ping', param, '4', host]
        
        try:
            output = subprocess.check_output(command).decode('gbk')
            if platform.system().lower() == 'windows':
                if '平均 = ' in output:
                    avg_time = output.split('平均 = ')[-1].split('ms')[0]
                    return {
                        "status": True,
                        "data": {"avg_time": avg_time},
                        "message": f"Ping测试成功，平均响应时间: {avg_time}ms"
                    }
            return {
                "status": True,
                "data": {"output": output},
                "message": output
            }
        except Exception as e:
            return {
                "status": False,
                "message": f"Ping测试失败: {str(e)}"
            }

    @staticmethod
    def start_speed_test() -> Dict:
        """
        @description 开始网速测试
        @returns {Dict} 网速测试结果
        """
        try:
            st = speedtest.Speedtest()
            st.get_best_server()
            
            # 测试下载速度
            download_speed = st.download() / 1_000_000  # 转换为Mbps
            
            # 测试上传速度
            upload_speed = st.upload() / 1_000_000
            
            return {
                "status": True,
                "data": {
                    "download": round(download_speed, 2),
                    "upload": round(upload_speed, 2)
                },
                "message": f"下载速度: {round(download_speed, 2)} Mbps\n上传速度: {round(upload_speed, 2)} Mbps"
            }
        except Exception as e:
            return {
                "status": False,
                "message": f"速度测试失败: {str(e)}"
            }

    @staticmethod
    def diagnose_network() -> Dict:
        """
        @description 全面的网络诊断
        @returns {Dict} 诊断结果
        """
        results = {
            "status": True,
            "tests": {},
            "message": "诊断完成"
        }

        # DNS解析测试
        dns_result = NetworkUtils.test_dns_resolution()
        results["tests"]["dns"] = dns_result

        # 网关连通性测试
        gateway = NetworkUtils.get_default_gateway()
        gateway_result = NetworkUtils.ping_test(gateway) if gateway else {
            "status": False,
            "message": "无法获取默认网关"
        }
        results["tests"]["gateway"] = gateway_result

        # 公网连通性测试
        internet_result = NetworkUtils.check_internet_connection()
        results["tests"]["internet"] = internet_result

        # 常见端口测试
        port_result = NetworkUtils.test_common_ports()
        results["tests"]["ports"] = port_result

        return results

    @staticmethod
    def test_dns_resolution(domains: List[str] = None) -> Dict:
        """
        @description DNS解析测试
        @param {List[str]} domains - 要测试的域名列表
        @returns {Dict} DNS测试结果
        """
        if domains is None:
            domains = ["www.baidu.com", "www.google.com", "www.microsoft.com"]

        results = {}
        resolver = dns.resolver.Resolver()
        resolver.timeout = 3
        resolver.lifetime = 3

        for domain in domains:
            try:
                start_time = time.time()
                answers = resolver.resolve(domain, 'A')
                resolution_time = round((time.time() - start_time) * 1000, 2)
                
                results[domain] = {
                    "status": True,
                    "ips": [str(rdata) for rdata in answers],
                    "time": resolution_time
                }
            except Exception as e:
                results[domain] = {
                    "status": False,
                    "error": str(e)
                }

        return {
            "status": True,
            "data": results,
            "message": "DNS测试完成"
        }

    @staticmethod
    def get_default_gateway() -> str:
        """
        @description 获取默认网关地址
        @returns {str} 网关IP地址
        """
        try:
            if platform.system().lower() == 'windows':
                output = subprocess.check_output('ipconfig', text=True)
                for line in output.split('\n'):
                    if '默认网关' in line or 'Default Gateway' in line:
                        gateway = line.split(':')[-1].strip()
                        if gateway and gateway != '0.0.0.0':
                            return gateway
            return None
        except:
            return None

    @staticmethod
    def test_common_ports(host: str = "localhost", ports: List[int] = None) -> Dict:
        """
        @description 测试常见端口
        @param {str} host - 目标主机
        @param {List[int]} ports - 要测试的端口列表
        @returns {Dict} 端口测试结果
        """
        if ports is None:
            ports = [80, 443, 53, 8080]  # 常见端口

        results = {}
        for port in ports:
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(2)
                result = sock.connect_ex((host, port))
                sock.close()
                
                results[port] = {
                    "status": result == 0,
                    "state": "open" if result == 0 else "closed"
                }
            except Exception as e:
                results[port] = {
                    "status": False,
                    "error": str(e)
                }

        return {
            "status": True,
            "data": results,
            "message": "端口测试完成"
        }

    @staticmethod
    def detailed_speed_test() -> Dict:
        """
        @description 详细的网速测试
        @returns {Dict} 详细的网速测试结果
        """
        try:
            st = speedtest.Speedtest()
            st.get_best_server()
            
            # 测试下载速度
            download_speed = st.download() / 1_000_000  # 转换为Mbps
            
            # 测试上传速度
            upload_speed = st.upload() / 1_000_000

            # 获取服务器信息
            server = st.get_best_server()
            
            return {
                "status": True,
                "data": {
                    "download": round(download_speed, 2),
                    "upload": round(upload_speed, 2),
                    "ping": round(server['latency'], 2),
                    "server": {
                        "name": server['sponsor'],
                        "location": f"{server['name']}, {server['country']}",
                        "latency": round(server['latency'], 2)
                    }
                },
                "message": (
                    f"下载速度: {round(download_speed, 2)} Mbps\n"
                    f"上传速度: {round(upload_speed, 2)} Mbps\n"
                    f"延迟: {round(server['latency'], 2)} ms\n"
                    f"测试服务器: {server['sponsor']} ({server['name']}, {server['country']})"
                )
            }
        except Exception as e:
            return {
                "status": False,
                "message": f"速度测试失败: {str(e)}"
            } 